/**
 * 通用方法.
 */
import { oss_url } from '@/pinia/getter'
import { ToastError } from './public'
export function parseTime(time: string | number | Date, Format?: string) {
    if(!time) return
    if (arguments.length === 0) {
        return null
    }
    const format = Format || '{y}-{m}-{d} {h}:{i}:{s}'
    let date
    if (typeof time === 'object') {
        date = time
    } else {
        if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
            time = parseInt(time)
        }
        if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000
        }
        date = new Date(time)
    }
    const formatObj:object | any = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
    const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result: string | any[], key: string) => {
        let value = formatObj[key]
            // Note: getDay() returns 0 on Sunday
        if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
        if (result.length > 0 && value < 10) {
            value = '0' + value
        }
        return value || 0
    })
    return time_str
}

/**
 * @param {Sting} input value
 * @returns {number} output value
 */

export function cleanArray(actual: string | any[]) {
    let newArray:Array<any> = []
    for (let i = 0; i < actual.length; i++) {
        if (actual[i]) {
            newArray.push(actual[i])
        }
    }
    return newArray
}

export function param(json: { [x: string]: string | number | boolean }) {
    if (!json) return ''
    return cleanArray(
        Object.keys(json).map(key => {
            if (json[key] === undefined) return ''
            return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
        })
    ).join('&')
}

export function getTime(type: string) {
    if (type === 'start') {
        return new Date().getTime() - 3600 * 1000 * 24 * 90
    } else {
        return new Date(new Date().toDateString())
    }
}

export const debounce = (fn:Function,delay=1000) => {
    let timer = 0
    return function (...args:any) {
        if(timer) return
        fn.apply(fn,args)
        timer = setTimeout(()=>{
            timer && clearTimeout(timer)
            timer = 0
        },delay)
    }
}
export const throttle = (fn:Function,delay=1000) => {
    let timer = 0
    return function (...args:any) {
        if(timer) return
        timer = setTimeout(()=>{
            fn.apply(fn,args)
            timer && clearTimeout(timer)
            timer = 0
        },delay)
    }
}

export function dateFormatter(str: string | number | Date) { // 默认返回yyyy-MM-dd HH-mm-ss
    const hasTime = arguments[1] !== false // 可传第二个参数false，返回yyyy-MM-dd
    const d = new Date(str)
    const year = d.getFullYear()
    const month = (d.getMonth() + 1) < 10 ? '0' + (d.getMonth() + 1) : (d.getMonth() + 1)
    const day = d.getDate() < 10 ? '0' + d.getDate() : d.getDate()
    const hour = d.getHours() < 10 ? '0' + d.getHours() : d.getHours()
    const minute = d.getMinutes() < 10 ? '0' + d.getMinutes() : d.getMinutes()
    const second = d.getSeconds() < 10 ? '0' + d.getSeconds() : d.getSeconds()
    if (hasTime) {
        return [year, month, day].join('-') + ' ' + [hour, minute, second].join(':')
    } else {
        return [year, month, day].join('-')
    }
}

export function number_format(number: string, decimals: number, dec_point: any, thousands_sep: any) {
    number = (number + '').replace(/[^0-9+-Ee.]/g, '')
    let n = !isFinite(+number) ? 0 : +number,
        prec = !isFinite(+decimals) ? 2 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        s:any = '',
        toFixedFix = function(n: number, prec: number) {
            let k = Math.pow(10, prec)
            return '' + Math.ceil(n * k) / k
        }

    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
    let re = /(-?\d+)(\d{3})/
    while (re.test(s[0])) {
        s[0] = s[0].replace(re, '$1' + sep + '$2')
    }

    if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
    }
    return s.join(dec)
}

//时间补零
function dateRounding(m:number) {
    return m < 10 ? "0" + m : m;
}


interface getDataForm {
    getTime:number
    symbol?:string
}
/**
 * 获取当前日期 年月日 默认为 new Date
 * getTime：时间戳，symbol：拼接符
 */
export function getData(obj={} as getDataForm) {
    const { getTime=new Date().getTime(), symbol='-' } = obj
    const time = new Date(getTime);
    const y = time.getFullYear();
    const m = time.getMonth() + 1;
    const d = time.getDate();
    return y + symbol + dateRounding(m) + symbol + dateRounding(d)
}

/**
 * 获取当天-第二天时间戳
 * @param type 
 * ymdhis 年月日小时分钟秒 
 * ymdh 年月日小时
 * ymd 年月日
 * year 月的开始结束
 * canon 年月日
 * time 时间戳
 * GMT 标准时间
 * @returns [开始时间，结束时间]
 */
export const getDateArray = (type='')=> {
    if(!type) {
        return [
            getData(),
            getData()
        ]
    }
    // 当前日 0点时间
    const time = new Date(getData({getTime:new Date().getTime(),symbol:'/'})).getTime()
    if(type == 'ymdhis') {
        return [
            getHMMSS(time),
            getHMMSS(time + 86400000)
        ]
    }
    if(type == 'ymdh') {
      // console.log(type);
      return [
          getHMMSS(time,'ymdh'),
          getHMMSS(time + 86400000,'ymdh')
      ]
    }
    if(type == 'ymd') {
        return [
            getData({getTime:time,symbol:'-'}),
            getData({getTime:time + 86400000,symbol:'-'})
        ]
    }
    if(type == 'canon') {
        return [
            getData(),
            getData({getTime:new Date().getTime() + 86400000})
        ]
    }
    if(type == 'time') {
        return [
            new Date(getData() + ' 00:00:00').getTime(),
            new Date(getData() + ' 00:00:00').getTime() + 86400000
        ]
    }
    if(type == 'year') {
        const { playTime, endTime } = getMonthTime(time)
        return [
            playTime,
            endTime
        ]
    }
    if(type == 'GMT') {
        const date = new Date(getData() + ' 00:00:00')
        const endDate = new Date(date).getTime() + 86400000
        return [
            date,
            new Date(endDate)
        ]
    }
}
/**
 * ymdhis 年月日小时分钟秒 
 * playTime 开始
 * endTime 结束
 * @param dateArr datapicker 选择的时间数组 时间戳转 日期格式
 * @returns 
 * '{ playTime:开始时间, endTime:结束时间 }'
 */
export function getPlayEndTime(dateArr:Array<any>=[], type='') {
    let obj:any = {
        playTime:0,
        endTime:0,
    }
    if(Array.isArray(dateArr) && dateArr.length > 0) {
        if(Number(dateArr[0]) && Number(dateArr[1])) {
            if(type == 'ymdhis') {
                obj = {
                    playTime:getHMMSS(dateArr[0]),
                    endTime:getHMMSS(dateArr[1])
                }
            } else if(type == 'ymdh') {
              obj = {
                  playTime:getHMMSS(dateArr[0],'ymdh'),
                  endTime:getHMMSS(dateArr[1],'ymdh')
              }
            } else if(type == 'ymd') {
                obj = {
                    playTime:getData({getTime:dateArr[0]}),
                    endTime:getData({getTime:dateArr[1]})
                }
            } else {
                obj = {
                    playTime:Math.round(dateArr[0] / 1000),
                    endTime:Math.round(dateArr[1] / 1000)
                }
            }
        } else {
            obj = {
                playTime:dateArr[0],
                endTime:dateArr[1]
            }
        }
        
    }
    return obj
}
/**
 * 返回年月日时分秒
 * @param timestamp 时间戳 毫秒 
 * @param dayType ymdhms 包含字符即存在该日期
 * @returns y-mm-dd hh:mm:ss
 */
export function getHMMSS(timestamp: string | number | Date = new Date().getTime(), dayType:string ='ymdhms') {
    const time = new Date(timestamp);
    const year = time.getFullYear();
    const moon = dateRounding(time.getMonth() + 1);
    const sun = dateRounding(time.getDate());
    const hour = dateRounding(time.getHours());
    const minute = dateRounding(time.getMinutes());
    const second = dateRounding(time.getSeconds());
    const timeText = [
      { type:'ymd',text:`${year}-${moon}-${sun}` },
      { type:'ymdh',text:`${year}-${moon}-${sun} ${hour}:00:00` },
      { type:'ymdhms',text:`${year}-${moon}-${sun} ${hour}:${minute}:${second}` },
    ].find(res=>res.type == dayType)?.text || ''
    if(!timeText) {
      ToastError('getHMMSS function dayType 不存在该类型 请添加')
      return ''
    }
    // console.log(dayType, timeText);
    return timeText
}
/**
 * 
 * @param time 日期
 * @param type m毫秒级时间戳 s秒级时间戳
 * @returns timestamp:number
 */
export function getTimestamp(time:string,type:string = 'm') {
    const timeNum = new Date(time).getTime()
    if(type == 'm') {
        return timeNum
    }
    if(type == 's') {
        return Math.round(timeNum / 1000)
    }
}
/**
 * 获取一月前第一天日期
 * @param timestamp 
 * @returns timestamp
 */
export function getLastData(timestamp: string | number | Date = new Date().getTime()) {
    const time = new Date(timestamp);
    const y = time.getFullYear();
    const m = time.getMonth() + 1;
    return new Date(`${y}-${dateRounding(m)}-01`).getTime()
}
/**
 * 
 * @returns 获取本周第一天
 */
export function weekStarts() {
    const date = new Date(getData())
    return new Date(date.getTime() - (3600 * 1000 * 24 * (date.getDay() == 0 ? 6 : date.getDay()-1))).getTime()
}
/**
 * 获取周的playTime开始 endTime结束
 * @param time 时间戳 毫秒
 * @returns
 * '{ playTime:开始时间, endTime:结束时间 }'
 */
export function getWeeKTime(time:number = 0) {
    if(!time) {
        console.error('time as number ', +time)
        return {
            playTime:'',
            endTime:''
        }
    } 
    const date = new Date(time)
    let end=new Date(date.getTime()+(3600*1000*24* (date.getDay()==0 ? 0:7- date.getDay()))).getTime()
    return {
        playTime:getData({getTime:new Date(time).getTime()}),
        endTime:getData({getTime:end})
    }
}
/**
 * 获取月的playTime开始 endTime结束
 * @param time 时间戳 毫秒
 * @returns 
 * '{ playTime:开始时间, endTime:结束时间 }'
 */
export function getMonthTime(time:number = 0) {
    if(!time) {
        console.error('time as number ', +time)
        return {
            playTime:'',
            endTime:''
        }
    }  
    const date = new Date(time)
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    const lastDay = new Date(year, month, 0).getDate();
    return {
        playTime:`${year}-${dateRounding(month)}-01`,
        endTime:`${year}-${dateRounding(month)}-${dateRounding(lastDay)}`
    }
}
/**
 * 读取文件 
 * @param file 文件
 * @returns 
 */
export const readFile = (file: Blob) => {
    return new Promise(resolve => {
        let reader = new FileReader()
        reader.readAsBinaryString(file)
        reader.onload = (ev:any) => {
            resolve(ev.target.result)
        }
    })
}
/**
 * 文件下载
 * @param url 文件地址 缺少http https拼接 oss_url
 * @returns 
 */
export const Download = (url:string = '') => {
    if(!url) return console.error('url null')
    let href = url
    if(url.indexOf('http') < 0 && url.indexOf('https') < 0) {
        href = oss_url.value + url
    }
    const a = document.createElement('a');
    a.style.display = 'none';
    a.setAttribute('target', '_blank');
    a.href = href;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}
export const utf16toEntities = (str:any)=>{
    const patt = /[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则
    str = str.replace(patt, (char:any) => {
    let H;
    let L;
    let code;
    let s;

    if (char.length === 2) {
        H = char.charCodeAt(0); // 取出高位
        L = char.charCodeAt(1); // 取出低位
        code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00; // 转换算法
        s = `&#${code};`;
    } else {
        s = char;
    }

    return s;
    });
    return str;
}
/**
 * el-table 自定义合计 param默认回调参数 shield所需要屏蔽合计的下标
 * unitArr {key:0,unit:''}
 * @param param 
 * @returns 
 */
export const getSummaries = (param:any = {},shield:Array<number> = [],unitArr:Array<any>=[])=>{
    const { columns, data } = param;
    const sums:Array<any> = [];
      columns.forEach((column:any, index:any) => {
        const values = data.map((item:any) => Number(item[column.property]));
        if(index == 0) {
          sums[index] = '合计';
        }else if(shield.indexOf(index) > -1) {
          sums[index] = '';
        }else if (!values.every((value:any) => isNaN(value))) {
          sums[index] = values.reduce((prev:any, curr:any) => {
            const value = Number(curr);
            if (!isNaN(value)) {
              return prev + curr;
            } else {
              return prev;
            }
          }, 0);
          if(unitArr.length > 0) {
            const { key,unit='' } = unitArr.find(res=>res.key == index) || {key:-1}
            if(key > -1) sums[key] = `${sums[key]}${unit || ''}`
          }
        } else {
          sums[index] = '';
        }
      });
    return sums
  }